//
//  GLView.mm
//  Blend
//
//  Created by wq on 11-8-24.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "GLView.h"
#import "glues.h"

#define kColorBufferIdx 0
#define kDepthBufferIdx 1

@interface GLView ()

-(void)createBuffers;
-(void)deleteBuffers;

@end


@implementation GLView

@dynamic context;

+(Class)layerClass {
	return [CAEAGLLayer class];
}

- (id)initWithFrame:(CGRect)frame {
	
	self = [super initWithFrame:frame];
	if (self) {
		CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
		eaglLayer.opaque = TRUE;
		eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
										[NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
										kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
										nil];
	}
	return self;
}

- (void)dealloc {
	[context release];
	[super dealloc];
}

-(EAGLContext *)context {
	return context;
}

-(void)setContext:(EAGLContext *)ctx {
	if (context != ctx) {
		[self deleteBuffers];
		[EAGLContext setCurrentContext:nil];
		[context release];
		context = [ctx retain];
		[self createBuffers];
	}
}

-(void)createBuffers {
	if (context && !frameBuffer) {
		[EAGLContext setCurrentContext:context];
		
		glGenFramebuffersOES(1, &frameBuffer);
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, frameBuffer);
		
		glGenRenderbuffersOES(2, renderBuffers);
		glBindRenderbufferOES(GL_RENDERBUFFER_OES, renderBuffers[kColorBufferIdx]);
		[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer];
		
		glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, renderBuffers[kColorBufferIdx]);
		
		GLint frameWidth = 0;
		GLint frameHeight = 0;
		glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &frameWidth);
		glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &frameHeight);
		
		glBindRenderbufferOES(GL_RENDERBUFFER_OES, renderBuffers[kDepthBufferIdx]);
		glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, frameWidth, frameHeight);
		
		glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, renderBuffers[kDepthBufferIdx]);
		
		if (GL_FRAMEBUFFER_COMPLETE_OES != glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)) {
			NSLog(@"createBuffers failed!!!");
			exit(-1);
		}
	}
}

-(void)deleteBuffers {
	if (context && frameBuffer) {
		[EAGLContext setCurrentContext:context];
		
		glDeleteFramebuffersOES(1, &frameBuffer);
		frameBuffer = 0;
		
		glDeleteRenderbuffersOES(2, renderBuffers);
		renderBuffers[kColorBufferIdx] = 0;
		renderBuffers[kDepthBufferIdx] = 0;
	}
}

-(void)initViewport {
	CGSize size = self.bounds.size;
	glViewport(0, 0, size.width, size.height);
	
	glMatrixMode(GL_PROJECTION);
	
#if PROJECTION_PERSPECTIVE
	// 透视投影
	gluPerspectivef(60.0f, size.width / size.height, 100.0f, 1000.0f);
#else
	// 正投影
	glOrthof(-size.width / 2, size.width / 2, -size.height / 2, size.height / 2, -10.0f, 10.0f);
#endif
	
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glClearDepthf(1.0f);
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glShadeModel(GL_SMOOTH);
	
	glMatrixMode(GL_MODELVIEW);
}

-(BOOL)presentRenderbuffer {
	if (context) {
		[EAGLContext setCurrentContext:context];
		glBindRenderbufferOES(GL_RENDERBUFFER_OES, renderBuffers[kColorBufferIdx]);
		return [context presentRenderbuffer:GL_RENDERBUFFER_OES];
	}
	return NO;
}

@end
